package com.crm.system.controller.returnMoney;

import cn.hutool.http.HttpException;
import cn.hutool.http.HttpUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.DataResponse;
import com.crm.common.model.DhPageInfo;
import com.crm.common.model.DhResponse;
import com.crm.common.model.Enum.ResponseCodeEnum;
import com.crm.common.util.*;
import com.crm.model.entity.customerManager.Customer;
import com.crm.model.entity.orderManager.CustomerProductOrder;
import com.crm.model.entity.report.ReportPerformanceTop;
import com.crm.model.entity.returnMoney.BankFlow;
import com.crm.model.entity.returnMoney.ReturnMoney;
import com.crm.model.entity.sys.UserAccount;
import com.crm.model.entity.sys.permissionManagement.SysCompany;
import com.crm.model.entity.systemManager.SysParameterSetting;
import com.crm.model.qo.productManager.AnalyseReturnMoneyProductQO;
import com.crm.model.qo.returnMoney.BankFlowRelateQO;
import com.crm.model.qo.returnMoney.ReturnMoneyQO;
import com.crm.model.vo.customerManager.CustomerOrderBackMoneyVO;
import com.crm.model.vo.orderManager.CustomerProductOrderVO;
import com.crm.model.vo.orderManager.ImportOrderNumber;
import com.crm.model.vo.orderManager.PerformanceRankVO;
import com.crm.model.vo.productManager.AnalyseReturnMoneyProductVO;
import com.crm.model.vo.productManager.PerformanceAnalysisVO;
import com.crm.model.vo.productManager.ShelfProductsVO;
import com.crm.model.vo.returnMoney.*;
import com.crm.service.customerManager.CustomerDbService;
import com.crm.service.orderManager.CustomerProductOrderDbService;
import com.crm.system.service.cluePoolManager.ExcelUtil;
import com.crm.system.service.returnMoney.BankFlowService;
import com.crm.system.service.returnMoney.ReturnMoneyService;
import com.crm.system.service.systemManager.ParameterSettingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 回款管理
 */
@RestController
@RequestMapping("/returnMoney")
@Slf4j
public class ReturnMoneyController {

    @Value("${esurl}")
    public String ESurl;

    @Autowired
    private CustomerDbService customerDbService;

    @Autowired
    private ReturnMoneyService returnMoneyService;

    @Autowired
    private CustomerProductOrderDbService productOrderDbService;

    @Autowired
    private ParameterSettingService parameterSettingService;

    @Autowired
    private BankFlowService bankFlowService;
    /**
     * 管理端-回款列表
     * @return
     */
    @PostMapping("/selectReturnMoneyList")
    public DataResponse selectCustomerProductList(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                                  @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                                  @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                                  @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                                  ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<ReturnMoneyVO> customerProductVODhPageInfo = returnMoneyService.selectCustomerProductList(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),customerProductVODhPageInfo);
        }catch(Exception e){
            log.error("returnMoney selectReturnMoneyList error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }


    /**
     * 导出查询的内容
     * @param returnMoneyQO
     * @param response
     * @return
     */
    @GetMapping("/exportReturnMoneyList")
    public DataResponse exportReturnMoneyList(ReturnMoneyQO returnMoneyQO,HttpServletResponse response){
        try{
            String fileName = "回款记录"+System.currentTimeMillis();
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" +new String(fileName.getBytes(), "ISO8859-1") + ".xlsx");
            if(returnMoneyService.exportReturnMoneyList(returnMoneyQO,response)){
                return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),"导出成功");
            }
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode(),"导出失败");
        }catch(Exception e){
            log.error("returnMoney selectReturnMoneyList error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }



    /**
     * 分公司财务统计回款列表
     * @return
     */
    @PostMapping("/selectStatReturnMoney")
    public DataResponse selectStatReturnMoney(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                                  @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                                  @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                                  @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                                  ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<ReturnMoneyVO> customerProductVODhPageInfo = returnMoneyService.selectStatReturnMoney(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),customerProductVODhPageInfo);
        }catch(Exception e){
            log.error("returnMoney selectStatReturnMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 总部财务统计回款列表
     * @return
     */
    @PostMapping("/selectSuperStatReturnMoney")
    public DataResponse selectSuperStatReturnMoney(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                                  @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                                  @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                                  @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                                  ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<ReturnMoneyVO> customerProductVODhPageInfo = returnMoneyService.selectSuperStatReturnMoneyPage(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),customerProductVODhPageInfo);
        }catch(Exception e){
            log.error("returnMoney selectSuperStatReturnMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 分公司财务统计退款列表
     * @return
     */
    @PostMapping("/selectStatBackMoney")
    public DataResponse selectStatBackMoney(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                            @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                            @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                            @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                            ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<ReturnMoneyVO> customerProductVODhPageInfo = returnMoneyService.selectStatBackMoneyPage(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),customerProductVODhPageInfo);
        }catch(Exception e){
            log.error("returnMoney selectStatBackMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 查询退款统计信息
     * @return
     */
    @PostMapping("/selectOrderBackMoney")
    public DataResponse selectOrderBackMoney(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                            @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                            @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                            @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                            ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<CustomerOrderBackMoneyVO> customerProductVODhPageInfo = returnMoneyService.selectOrderBackMoney(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),customerProductVODhPageInfo);
        }catch(Exception e){
            log.error("returnMoney selectStatBackMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 总部财务统计退款列表
     * @return
     */
    @PostMapping("/selectSuperStatBackMoney")
    public DataResponse selectSuperStatBackMoney(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                                 @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                                 @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                                 @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                                 ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<ReturnMoneyVO> customerProductVODhPageInfo = returnMoneyService.selectSuperStatBackMoney(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),customerProductVODhPageInfo);
        }catch(Exception e){
            log.error("returnMoney selectStatBackMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 录入回款
     * @return
     */
    @PostMapping("/addReturnMoney")
    public DataResponse addReturnMoney(@RequestBody ReturnMoney returnMoney){
        try{
            Date date=new Date();
            SysParameterSetting set = parameterSettingService.selectSystemParameterSetting();
            //限制回款时间
            if (Objects.nonNull(set) && Objects.nonNull(set.getReturnMoneyDayNum())){
                LocalDate localDate = new LocalDate().minusDays(set.getReturnMoneyDayNum());
                if (Integer.valueOf(localDate.toString().substring(0,10).replaceAll("-","")) >
                        Integer.valueOf(DateUtil.dateFormat(returnMoney.getArriveTime()).substring(0,10).replaceAll("-",""))){
                    DataResponse response = new DataResponse();
                    response.setCode("RM0011");
                    response.setMessage("操作失败，只能录入近"+set.getReturnMoneyDayNum()+"天的回款");
                    return response;
                }
            }
            //每天超过16点不能录入回款
            SimpleDateFormat f =new  SimpleDateFormat("HH");
            String time=f.format(date);
            if (Integer.valueOf(time) > 15){
               // return new DhResponse(ResponseCodeEnum.RNTURN_MONEY_EXIST.getResponseCode());
            }
            //判断金额是否正常
            Map<String, Object> resultMap = returnMoneyService.mergeAddReturnMoneyMethod(returnMoney, 0,false);
            String resposeCode = resultMap.get("code").toString();
            CustomerProductOrderVO order=productOrderDbService.getOrderInfoById(returnMoney.getOrderId());
            Customer esVo = customerDbService.selectCustomerById(order.getCustomerId());
            syncES(esVo,esVo.getAccountId(),"财务审核-普通客户转会员");
            ESUtil.syncOrder(returnMoney.getOrderId(),ESurl);
            return new DhResponse(resposeCode);
        }catch(Exception e){
            log.error("returnMoney addReturnMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 录入回款、关联流水版
     * @return
     */
    @PostMapping("/addReturnMoneyJoinFlow")
    public DataResponse addReturnMoneyJoinFlow(@RequestBody ReturnMoney returnMoney){
        CustomerProductOrder order = productOrderDbService.selectProductOrderById(returnMoney.getOrderId());
        BigDecimal big = bankFlowService.selectCountAvailableAmount(returnMoney.getSerial(),order.getAffiliationCompanyId());
        if (big.compareTo(returnMoney.getArriveMoney()) == -1){
            return new DhResponse(ResponseCodeEnum.BANK_FLOW_AVAILABLE_IS_NULL.getResponseCode());
        }
        if (Objects.nonNull(returnMoney.getSerial())){
            BigDecimal arriveMoney = returnMoney.getArriveMoney();
            Map<String, String> map = new HashMap<>();
            map.put("code","000000");
            List<BankFlow> flows = bankFlowService.selectByTransactionNo(returnMoney.getSerial(),returnMoney.getOrderId());
            BankFlowRelateQO relateQO = new BankFlowRelateQO();
            relateQO.setArriveType(returnMoney.getArriveType());
            relateQO.setProductOrderId(returnMoney.getOrderId());
            relateQO.setTransactionNo(returnMoney.getSerial());
            relateQO.setRemark(returnMoney.getRemark());
            relateQO.setOrderNumber(order.getOrderNumber());
            relateQO.setPaymentUnit(returnMoney.getPaymentUnit());
            relateQO.setPaymentAccount(returnMoney.getPaymentAccount());
            relateQO.setPaymentBank(returnMoney.getPaymentBank());
            relateQO.setArriveAccountType(returnMoney.getArriveAccountType());
            relateQO.setCustomerId(order.getCustomerId());
            relateQO.setRelateType("D");
            relateQO.setArriveTime(DateUtil.formatDateTime(returnMoney.getArriveTime()));
            relateQO.setFinishOrderProductId(returnMoney.getFinishOrderProductId());
            relateQO.setFinishOrderProductNum(returnMoney.getFinishOrderProductNum());
            relateQO.setProductName(returnMoney.getProductName());
            relateQO.setProductCode(returnMoney.getProductNumber());
            relateQO.setOrderDetailType(returnMoney.getOrderDetailType());
            relateQO.setProductCategories(returnMoney.getProductCategories());
            relateQO.setProductId(returnMoney.getProductId());
            for (int i=0;i<flows.size() && new BigDecimal("0").compareTo(arriveMoney) == -1;i++){
                if (new BigDecimal("0").compareTo(flows.get(i).getAvailableAmount()) == -1){
                    relateQO.setFlowId(flows.get(i).getFlowId());
                    relateQO.setTransactionDate(flows.get(i).getTransactionDate());
                    relateQO.setCreditMoney(flows.get(i).getCreditMoney());
                    if (flows.get(i).getAvailableAmount().compareTo(arriveMoney) ==1 || flows.get(i).getAvailableAmount().compareTo(arriveMoney) ==0){
                        relateQO.setArriveMoney(returnMoney.getArriveMoney());
                    }else {
                        relateQO.setArriveMoney(returnMoney.getArriveMoney());
                    }
                    //relateQO.setArriveMoney(flows.get(i).getAvailableAmount());
                    arriveMoney = arriveMoney.subtract(relateQO.getArriveMoney());
                    try {
                        map = bankFlowService.relatedOrder(relateQO);
                        if (!ResponseCodeEnum.OK.equals(map.get("code"))){
                            return new DhResponse(map.get("code"), map.get("data"));
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }
            ESUtil.syncOrder(relateQO.getProductOrderId(),ESurl);
            String code = map.get("code");
            String data = map.get("data");
            return new DhResponse(code, data);
        }else {
            return new DhResponse(ResponseCodeEnum.BANK_FLOW_NO_NOT_EXIST.getResponseCode());
        }
    }

    /**
     * 修改回款信息
     * @return
     */
    @PostMapping("/updateReturnMoney")
    public DataResponse updateReturnMoney(@RequestBody ReturnMoney returnMoney){
        try{
            Date date=new Date();
            SysParameterSetting set = parameterSettingService.selectSystemParameterSetting();
            //限制回款时间
            if (Objects.nonNull(set) && Objects.nonNull(set.getReturnMoneyDayNum())){
                LocalDate localDate = new LocalDate().minusDays(set.getReturnMoneyDayNum());
                if (Integer.valueOf(localDate.toString().substring(0,10).replaceAll("-","")) >
                        Integer.valueOf(DateUtil.dateFormat(returnMoney.getArriveTime()).substring(0,10).replaceAll("-",""))){
                    DataResponse response = new DataResponse();
                    response.setCode("RM0011");
                    response.setMessage("操作失败，只能录入近"+set.getReturnMoneyDayNum()+"天的回款");
                    return response;
                }
            }
            //判断金额是否正常
            boolean b=returnMoneyService.ifReturnMoney(returnMoney);
            if (!b){
                return new DhResponse(ResponseCodeEnum.RNTURN_MONEY_TOOBIG.getResponseCode());
            }
            //订单是否作废
            b=returnMoneyService.orderIfAbolish(returnMoney);
            if (!b){
                return new DhResponse(ResponseCodeEnum.UPDATE_RNTURN_MONEY_ABOLISH.getResponseCode());
            }
            //到款时间
            b=Integer.valueOf(DateUtil.formatDateTime(returnMoney.getArriveTime()).substring(0,10).replaceAll("-","")) <= Integer.valueOf(DateUtils.getToday().replaceAll("-",""));
            if (!b){
                return new DhResponse(ResponseCodeEnum.RNTURN_MONEY_TIME_ERROR.getResponseCode());
            }
            String result = returnMoneyService.updateReturnMoney(returnMoney);
            return new DhResponse(result);
        }catch(Exception e){
            log.error("returnMoney addReturnMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 管理端-判断是否是超级管理员
     * @return
     */
    @GetMapping("/isSuperAdmin")
    public DataResponse selectCustomerProductList(){
        try{
            UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//获取登录人信息
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),CommonUtils.isAdmin(userAccount.getUserId()));
        }catch(Exception e){
            log.error("returnMoney isSuperAdmin error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 删除回款信息
     * @param returnMoneyId
     * @return
     */
    @PostMapping("/delReturnMoney")
    public DataResponse delReturnMoney(@RequestParam String returnMoneyId){
        try{
            boolean bo = returnMoneyService.delReturnMoney(returnMoneyId);
            if (!bo){
                return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
            }
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode());
        }catch(Exception e){
            log.error("returnMoney delReturnMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 导入回款记录
     * @param request
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/importReturnMoney")
    public DataResponse importReturnMoney(HttpServletRequest request,
                                          @RequestParam MultipartFile file,
                                          @RequestParam String companyId
    ) throws IOException {
        JSONObject jsonObject = new JSONObject();
        try {
            ExcelUtil excelUtil = new ExcelUtil();
            List<ImportReturnMoneyVO> list = excelUtil.excelImport(file.getInputStream(), ImportReturnMoneyVO.class);//1.读取前端的excel文件并转换成list集合
            if (list == null || list.size() == 0) {
                return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
            }
            jsonObject = returnMoneyService.importReturnMoney(list,companyId);

        } catch (Exception e) {
            log.error("returnMoney importReturnMoney:", e);
        }
        //返回导入数量、重复数量
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),jsonObject);
    }

    /**
     * 回款记录数据结构改变修改
     * @param request
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/importUpdateReturnMoney")
    public DataResponse importUpdateReturnMoney(HttpServletRequest request,
                                                @RequestParam MultipartFile file,
                                                @RequestParam String companyId
    ) throws IOException {
        JSONObject jsonObject = new JSONObject();
        try {
            ExcelUtil excelUtil = new ExcelUtil();
            List<ImportReturnMoneyVO> list = excelUtil.excelImport(file.getInputStream(), ImportReturnMoneyVO.class);//1.读取前端的excel文件并转换成list集合
            if (list == null || list.size() == 0) {
                return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
            }
            jsonObject = returnMoneyService.importUpdateReturnMoney(list,companyId);

        } catch (Exception e) {
            log.error("returnMoney importReturnMoney:", e);
        }
        //返回导入数量、重复数量
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),jsonObject);
    }

    /**
     * 导入退款记录
     * @param request
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/importBackMoney")
    public DataResponse importBackMoney(HttpServletRequest request,
                                        @RequestParam MultipartFile file,
                                        @RequestParam String companyId
    ) throws IOException {
        JSONObject jsonObject = new JSONObject();
        try {
            ExcelUtil excelUtil = new ExcelUtil();
            List<ImportBckMoneyVO> list = excelUtil.excelImport(file.getInputStream(), ImportBckMoneyVO.class);//1.读取前端的excel文件并转换成list集合
            if (list == null || list.size() == 0) {
                return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
            }
            jsonObject = returnMoneyService.importBackMoney(list,companyId);

        } catch (Exception e) {
            log.error("returnMoney importBackMoney:", e);
        }
        //返回导入数量、重复数量
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),jsonObject);
    }

    /**
     * 总部财务导出各公司到款信息
     * @param req
     * @param res
     * @param returnMoneyQO
     * @return
     * @throws IOException
     */
    @GetMapping(value="/exportReturnMoney")
    public void exportSysUsers(HttpServletRequest req, HttpServletResponse res,
                                       ReturnMoneyQO returnMoneyQO) throws Exception {
        List<ReturnMoneyVO> userList = returnMoneyService.selectSuperStatReturnMoney(returnMoneyQO);
        List<ExportReturnMoneyVO> list = new ArrayList<>();
        for (int i = 0; i < userList.size(); i++) {
            ExportReturnMoneyVO vo = new ExportReturnMoneyVO();
            vo.setFilialeName(userList.get(i).getFilialeName());
            vo.setScoreMoney(userList.get(i).getScoreMoney());
            vo.setArriveMoney(userList.get(i).getArriveMoney());
            list.add(vo);
        }
        ExcelUtil4 excelUtil = new ExcelUtil4();
        String fileName = "到款分析"+new Date().getTime() +".xlsx";
        excelUtil.writeExcel(res,list,fileName,"sheet1",ExportReturnMoneyVO.class);
    }

    /**
     * 总部财务导出各公司退款信息
     * @param req
     * @param res
     * @param returnMoneyQO
     * @return
     * @throws IOException
     */
    @GetMapping(value="/exportBckMoney")
    public void exportBckMoney(HttpServletRequest req, HttpServletResponse res,
                                       ReturnMoneyQO returnMoneyQO) throws Exception {
        // 查询数据导出即可 比如说一次性总共查询出100条数据
        List<ReturnMoneyVO> userList = returnMoneyService.selectStatBackMoney(returnMoneyQO);
        List<ExportBackMoneyVO> list = new ArrayList<>();
        for (int i = 0; i < userList.size(); i++) {
            ExportBackMoneyVO vo = new ExportBackMoneyVO();
            vo.setFilialeName(userList.get(i).getFilialeName());
            vo.setArriveMoney(userList.get(i).getArriveMoney());
            list.add(vo);
        }
        String fileName = "退款分析"+new Date().getTime() +".xlsx";
        ExcelUtil4 excelUtil = new ExcelUtil4();
        excelUtil.writeExcel(res,list,fileName,"sheet1",ExportBackMoneyVO.class);
    }

    /**
     * 订单回款错误关联
     * @param orderId
     * @param shiftOrderNumber
     * @return
     */
    @PostMapping("/shiftOrderReturnMoney")
    public DataResponse shiftOrderReturnMoney(String orderId, String shiftOrderNumber,String finishId,Integer type,BigDecimal returnMoney){
        String result = returnMoneyService.shiftOrderReturnMoney(orderId,shiftOrderNumber,finishId,type,returnMoney);
        return new DhResponse(result);
    }

    //测试订单产品、回款金额是否有益处
    @PostMapping("test")
    //public DataResponse testReturnMoneyAndProduct(String orderNumber){
    public DataResponse testReturnMoneyAndProduct(HttpServletRequest request,
                                                  @RequestParam MultipartFile file){
        ExcelUtil excelUtil = new ExcelUtil();
        List<String> list2= new ArrayList<>();
        try {
            List<ImportOrderNumber> list = excelUtil.excelImport(file.getInputStream(), ImportOrderNumber.class);//1.读取前端的excel文件并转换成list集合
            for (int i=0;i<list.size();i++){
                String orderNumber = list.get(i).getOrderNumber();
                orderNumber = orderNumber.replaceAll(" ","");
                orderNumber = orderNumber.replaceAll("\n","");
                boolean b = returnMoneyService.testReturnMoneyAndProduct(orderNumber);
                if (b){
                    list2.add(orderNumber);
                }else {

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new DhResponse(ResponseCodeEnum.OK.getResponseCode());
    }

    @PostMapping("/addReturnMoneyCustomerInfo")
    public DataResponse testReturnMoneyAndProduct(HttpServletRequest request,
                                                  @RequestParam MultipartFile file,
                                                  String companyId){
        ExcelUtil excelUtil = new ExcelUtil();
        try {
            List<ImportOrderNumber> list = excelUtil.excelImport(file.getInputStream(), ImportOrderNumber.class);//1.读取前端的excel文件并转换成list集合
            String resultMessage = returnMoneyService.addReturnMoneyCustomerInfo(companyId,list);
            if(!StringUtils.isBlank(resultMessage)){
                return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),resultMessage);
            }
        } catch (IOException e) {
            return new DhResponse(ResponseCodeEnum.SERVICE_ERROR.getResponseCode());
        }
        return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
    }

    /**
     * 财务明细
     * @return
     */
    @PostMapping("/selectFinancialDetails")
    public DataResponse selectFinancialDetails(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                              @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                              @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                              @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                              ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<FinancialDetailsVO> list = returnMoneyService.selectFinancialDetails(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),list);
        }catch(Exception e){
            log.error("returnMoney selectFinancialDetails error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 业绩明细
     * @return
     */
    @PostMapping("/selectPerformanceDetails")
    public DataResponse selectPerformanceDetails(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                               @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                               @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                               @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                               ReturnMoneyQO returnMoneyQO//查询条件
    ){
        try{
            DhPageInfo<PerformanceDetailsVO> list = returnMoneyService.selectPerformanceDetails(returnMoneyQO,pageIndex,pageSize,sortName,sortOrder);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),list);
        }catch(Exception e){
            log.error("returnMoney selectPerformanceDetails error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 按照年月查询业绩明细
     * @return
     */
    @PostMapping("/selectMonthPerformanceDetails")
    public DataResponse selectMonthPerformanceDetails(ReturnMoneyQO returnMoneyQO){
        try{
            List<PerformanceDetailsVO> list = returnMoneyService.selectMonthPerformanceDetails(returnMoneyQO);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),list);
        }catch(Exception e){
            log.error("returnMoney selectMonthPerformanceDetails error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    /**
     * 查询公司列表
     * @return
     */
    @PostMapping("/selectSysCompanyList")
    public DataResponse selectSysCompanyList(){
        try{
            List<SysCompany> list = returnMoneyService.selectSysCompanyList();
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),list);
        }catch(Exception e){
            log.error("returnMoney selectSysCompanyList error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }


    /*@PostMapping("/updateDate")
    public DataResponse updateDate(){
        try{
            Boolean rs = returnMoneyService.updateDate();
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),rs);
        }catch(Exception e){
            log.error("returnMoney updateDate error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }*/


    /**
     * 财务 导出到款记录
     * @Author baijian
     * @Date  2021/9/28 15:14
     * @param request
     * @param response
     * @param returnMoneyQO -查询条件
     * @return {@link }
     */
    @GetMapping(value="/exportPerformanceDetails")
    public void exportPerformanceDetails(HttpServletRequest request, HttpServletResponse response,
                                         ReturnMoneyQO returnMoneyQO) throws Exception {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码
            String fileName = URLEncoder.encode("业绩明细 "+ DateUtil.getDate("yyyy-MM-dd HH:mm:ss"), "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelUtil4.getHorizontalCellStyleStrategy();
            List<PerformanceDetailsVO> list = returnMoneyService.exportPerformanceDetails(returnMoneyQO);
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), PerformanceDetailsVO.class)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("业绩明细")
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .doWrite(list);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
            log.error("returnMoney exportPerformanceDetails error:", e);
        }
    }

    /**
     * 统计个人业绩总和
     * @return
     */
    @PostMapping("/sumScoreMoney")
    public DataResponse sumScoreMoney(ReturnMoneyQO returnMoneyQO){
        try{
            BigDecimal score = returnMoneyService.sumScoreMoney(returnMoneyQO);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),score);
        }catch(Exception e){
            log.error("returnMoney sumScoreMoney error:", e);
            return new DhResponse(ResponseCodeEnum.ERROR.getResponseCode());
        }
    }

    private void syncES(Customer customer,String accountId,String msg) {

        String token = getToken(accountId,msg);

        Map<String, Object> parMap = transBean2Map(customer);
        parMap.put("authorization",token);
        parMap.put("key",accountId);
        try {
            String result = HttpUtil.post(ESurl+"/cutomer/insertOrUpdate",parMap);
            log.info(ESurl +result +msg);
        } catch (HttpException e) {
            log.info(msg+"ES同步失败");
        }
    }

    private String getToken(String accountId, String msg) {
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("accountId", accountId);
        try {
            return HttpUtil.post(ESurl+"/token/initToken",tokenMap);
        } catch (Exception e) {
            log.info(msg+"获取token失败");
        }
        return null;
    }


    /**
     * 对象装换map
     * @param obj
     * @return
     */
    private static Map<String, Object> transBean2Map(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 得到property对应的getter方法
                Method getter = property.getReadMethod();
                Object value = getter.invoke(obj);
                map.put(key, value);
            }
        } catch (Exception e) {
            System.out.println("transBean2Map Error " + e);
        }
        return map;
    }

    /**
     * 报表统计 - 业绩分析 - 销售产品分析
     * @Author pym
     * @Date  2021/9/27 14:47
     * @param pageIndex -页码
     * @param pageSize -分页大小
     * @param sortName -排序列名字
     * @param sortOrder -排序规则(asc/desc)
     * @param analyseReturnMoneyProductQO -查询条件
     * @return {@link {com.crm.common.model.DataResponse}}
     */
    @PostMapping("/selectReturnMoneyProductList")
    public DataResponse selectReturnMoneyProductList(@RequestParam(value = "pageIndex", required = true) Integer pageIndex,//页码
                                                     @RequestParam(value = "pageSize", required = true) Integer pageSize,//分页大小
                                                     @RequestParam(value="sortName",required = false) String sortName,//排序列名字
                                                     @RequestParam(value="sortOrder",required = false) String sortOrder,//排序规则(asc/desc)
                                                     AnalyseReturnMoneyProductQO analyseReturnMoneyProductQO//查询条件
    ){
        try {
            DhPageInfo<AnalyseReturnMoneyProductVO> resultVo = returnMoneyService.selectReturnMoneyProductList(pageIndex,pageSize,sortName,sortOrder,analyseReturnMoneyProductQO);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), resultVo);
        }catch (Exception e){
            log.error("returnMoney selectProductAnalyse error:", e);
            return new DhResponse(ResponseCodeEnum.SERVICE_ERROR.getResponseCode());
        }
    }

    /**
     * 报表统计 - 业绩分析 - 销售产品分析 - 高级筛选 产品
     * @Author pym
     * @Date  2021/12/29 16:33
     * @param
     * @return {@link {com.crm.common.model.DataResponse}}
     */
    @GetMapping("/selectShelfProductList")
    public DataResponse selectShelfProductList(){
        try {
            ShelfProductsVO shelfProductsVO = returnMoneyService.selectShelfProductList();
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(), shelfProductsVO);
        }catch (Exception e){
            log.error("returnMoney selectShelfProductList error:", e);
            return new DhResponse(ResponseCodeEnum.SERVICE_ERROR.getResponseCode());
        }
    }

    /**
     * 报表统计 - 业绩分析 - 销售额度统计表
     * @Author pym
     * @Date  2021/10/21 9:58
     * @param analyseReturnMoneyProductQO -查询条件
     * @return {@link {com.crm.common.model.DataResponse}}
     */
    @GetMapping("/selectPerformanceAnalysis")
    public DataResponse selectPerformanceAnalysis(AnalyseReturnMoneyProductQO analyseReturnMoneyProductQO){
        try {
            PerformanceAnalysisVO performanceAnalysisVO = returnMoneyService.selectPerformanceAnalysis(analyseReturnMoneyProductQO);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),performanceAnalysisVO);
        }catch (Exception e){
            log.error("returnMoney selectPerformanceAnalysis error:", e);
            return new DhResponse(ResponseCodeEnum.SERVICE_ERROR.getResponseCode());
        }
    }

    /**
     * 双十一报表
     * @Author renshaorong
     * @Date 2021/11/3 
     * @param entryArea
     * @param month
     * @return
     */
    @GetMapping("/reportForNovember")
    public DataResponse reportForNovember(@RequestParam(required = false) String entryArea,@RequestParam(required = false) String year,@RequestParam(required = false) String month,@RequestParam(required = false) String day){
        try {
            List<PerformanceRankVO> performanceRankVOS = returnMoneyService.reportForNovember(entryArea,year,month,day);
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),performanceRankVOS);
        }catch (Exception e){
            log.error("returnMoney reportForNovember error:", e);
            return new DhResponse(ResponseCodeEnum.SERVICE_ERROR.getResponseCode());
        }
    }

    @GetMapping("/reportPerformanceTop")
    public DataResponse reportPerformanceTop(){
        try {
            List<ReportPerformanceTop> reportPerformanceTops = returnMoneyService.getReportPerformanceTop();
            return new DhResponse(ResponseCodeEnum.OK.getResponseCode(),reportPerformanceTops);
        }catch (Exception e){
            log.error("returnMoney reportPerformanceTop error:", e);
            return new DhResponse(ResponseCodeEnum.SERVICE_ERROR.getResponseCode());
        }
    }

}
